/**
 * 简洁的文件变更检测协议
 * 直接使用系统标准的 FileChange<T> 类型
 */
import {
  FileSnapshot,
  FileChange,
  FileChangeWithSide,
  ChangeAction,
  CompareSide,
} from '@/types/modules/editor/types/commit.type';

/**
 * 比对结果
 */
export interface CompareResult<T = any> {
  changes: FileChangeWithSide<T>[];
  summary: {
    total: number;
    added: number;
    modified: number;
    deleted: number;
  };
  duration: number; // 比对耗时（毫秒）
}

/**
 * 比对两个文件快照数组，检测变更
 * 返回带有方标识的 FileChangeWithSide<T> 类型
 */
export async function compareFileSnapshots<T = any>(
  sourceFiles: FileSnapshot[],
  targetFiles: FileSnapshot[],
  options: {
    projectId?: string;
    shadowSpace?: string;
    sourceLabel?: string; // 源方标识，如 'editor', 'local', 'user-A'
    targetLabel?: string; // 目标方标识，如 'shadow-space', 'remote', 'user-B'
  } = {},
): Promise<CompareResult<T>> {
  const startTime = performance.now();
  const changes: FileChangeWithSide<T>[] = [];
  const { projectId, shadowSpace, sourceLabel = 'source', targetLabel = 'target' } = options;

  // 构建文件映射，便于快速查找
  const sourceMap = new Map(sourceFiles.map((f) => [f.path, f]));
  const targetMap = new Map(targetFiles.map((f) => [f.path, f]));

  let changeCounter = 0;

  // 检测新增和修改
  for (const [path, targetFile] of targetMap) {
    const sourceFile = sourceMap.get(path);

    if (!sourceFile) {
      // 新增文件 - 来自目标方
      changes.push({
        id: `change_${Date.now()}_${++changeCounter}`,
        action: 'add',
        path,
        version: 1,
        timestamp: targetFile.modify,
        diff: {
          after: {} as Partial<T>, // 实际内容由调用方提供
        },
        author: String(targetFile.updateBy),
        projectId,
        shadowSpace,
        side: 'target',
        sourceLabel,
        targetLabel,
      });
    } else if (sourceFile.hash !== targetFile.hash) {
      // 修改文件 - 目标方有变更
      changes.push({
        id: `change_${Date.now()}_${++changeCounter}`,
        action: 'modify',
        path,
        version: 2, // 简化版本处理
        timestamp: targetFile.modify,
        diff: {
          before: {} as Partial<T>, // 实际内容由调用方提供
          after: {} as Partial<T>,
        },
        author: String(targetFile.updateBy),
        projectId,
        shadowSpace,
        side: 'target',
        sourceLabel,
        targetLabel,
      });
    }
    // 哈希相同则跳过，无变更
  }

  // 检测删除
  for (const [path, sourceFile] of sourceMap) {
    if (!targetMap.has(path)) {
      // 删除文件 - 源方有但目标方没有
      changes.push({
        id: `change_${Date.now()}_${++changeCounter}`,
        action: 'delete',
        path,
        version: 1,
        timestamp: Date.now(),
        diff: {
          before: {} as Partial<T>, // 实际内容由调用方提供
        },
        author: String(sourceFile.updateBy),
        projectId,
        shadowSpace,
        side: 'source',
        sourceLabel,
        targetLabel,
      });
    }
  }

  const duration = performance.now() - startTime;

  // 统计变更
  const summary = {
    total: changes.length,
    added: changes.filter((c) => c.action === 'add').length,
    modified: changes.filter((c) => c.action === 'modify').length,
    deleted: changes.filter((c) => c.action === 'delete').length,
  };

  return { changes, summary, duration };
}
